/**
 * @author Nicolas Latorre (nicolas.latorre@usi.ch)
 * @author Nicolas Zimerman (zimerman@usi.ch)
 */
package ch.usi.inf.pf2.file.interaction;

import ch.usi.inf.pf2.circuit.AndGate;
import ch.usi.inf.pf2.circuit.OrGate;
import ch.usi.inf.pf2.circuit.XorGate;
import ch.usi.inf.pf2.circuit.NotGate;
import ch.usi.inf.pf2.circuit.NandGate;
import ch.usi.inf.pf2.circuit.NorGate;
import ch.usi.inf.pf2.circuit.Output;
import ch.usi.inf.pf2.circuit.Component;
import ch.usi.inf.pf2.circuit.Input;
import ch.usi.inf.pf2.circuit.Wire;
import java.util.ArrayList;

public class Parser {
	private final Lexer lexer;
	private InstructionReader reader;
	private ArrayList<Component> circuit;
	
	public Parser(String location) {
		reader = new InstructionReader(location);
		lexer = new Lexer(reader.getText());
		circuit = new ArrayList<Component>();
	}
	
	public void parse() {
		lexer.fetchNextToken();
		if(lexer.getCurrentToken().getType() == TokenType.INPUT) {
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int x = Integer.parseInt(lexer.getCurrentToken().getText());
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int y = Integer.parseInt(lexer.getCurrentToken().getText());
			circuit.add(new Input(x, y));
			parse();
		}
		else if(lexer.getCurrentToken().getType() == TokenType.AND_GATE) {
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int x = Integer.parseInt(lexer.getCurrentToken().getText());
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int y = Integer.parseInt(lexer.getCurrentToken().getText());
			circuit.add(new AndGate(x, y));
			parse();
		}
		else if(lexer.getCurrentToken().getType() == TokenType.OR_GATE) {
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int x = Integer.parseInt(lexer.getCurrentToken().getText());
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int y = Integer.parseInt(lexer.getCurrentToken().getText());
			circuit.add(new OrGate(x, y));
			parse();
		}
		else if(lexer.getCurrentToken().getType() == TokenType.XOR_GATE) {
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int x = Integer.parseInt(lexer.getCurrentToken().getText());
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int y = Integer.parseInt(lexer.getCurrentToken().getText());
			circuit.add(new XorGate(x, y));
			parse();
		}
		else if(lexer.getCurrentToken().getType() == TokenType.NOT_GATE) {
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int x = Integer.parseInt(lexer.getCurrentToken().getText());
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int y = Integer.parseInt(lexer.getCurrentToken().getText());
			circuit.add(new NotGate(x, y));
			parse();
		}
		else if(lexer.getCurrentToken().getType() == TokenType.NAND_GATE) {
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int x = Integer.parseInt(lexer.getCurrentToken().getText());
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int y = Integer.parseInt(lexer.getCurrentToken().getText());
			circuit.add(new NandGate(x, y));
			parse();
		}
		else if(lexer.getCurrentToken().getType() == TokenType.NOR_GATE) {
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int x = Integer.parseInt(lexer.getCurrentToken().getText());
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int y = Integer.parseInt(lexer.getCurrentToken().getText());
			circuit.add(new NorGate(x, y));
			parse();
		}
		else if(lexer.getCurrentToken().getType() == TokenType.OUTPUT) {
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int x = Integer.parseInt(lexer.getCurrentToken().getText());
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int y = Integer.parseInt(lexer.getCurrentToken().getText());
			circuit.add(new Output(x, y));
			parse();
		}
		else if(lexer.getCurrentToken().getType() == TokenType.WIRE) {
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int x = Integer.parseInt(lexer.getCurrentToken().getText());
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int y = Integer.parseInt(lexer.getCurrentToken().getText());
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int v = Integer.parseInt(lexer.getCurrentToken().getText());
			lexer.fetchNextToken();
			lexer.fetchNextToken();
			int z = Integer.parseInt(lexer.getCurrentToken().getText());
			circuit.add(new Wire(x, y, v, z));
			parse();
		}
	}
	
	public ArrayList<Component> getCircuit() {
		return circuit;
	}
	
}